package net.kong.sns.rest.client;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
import net.kong.sns.rest.client.rest.RestClient.RestParameters;

/**
 * @author <a href="mailto:lanhuai@gmail.com">Ning Yubin</a>
 * @version $Id: SignatureUtils.java,v 1.3.2.1 2009/12/29 07:47:20 wangyuanming Exp $
 */
public abstract class SignatureUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(SignatureUtils.class);

    public static void signParameterMap(Map<String, String> params, String sessionKey, String apiSecret, String httpMethod, String url) {
        if (sessionKey != null) {
            params.put(RestParameters.SESSION_KEY, sessionKey);
        }
        String signature = generateSignature(params, apiSecret, httpMethod, url);
        params.put(RestParameters.SIGNATURE, signature);
    }

    public static String generateSignature(Map<String, String> parameterMap, String apiSecret, String httpMethod, String url) {
        StringBuffer sb = new StringBuffer();
        List<String> keys = new ArrayList<String>(parameterMap.keySet());
        Collections.sort(keys);
        for (int x = 0; x < keys.size(); x++) {
            String key = keys.get(x);
            String value = parameterMap.get(key);
            if (x > 0) {
                sb.append('&');
            }
            sb.append(key);
            sb.append("=");
            sb.append(value);
        }
        String p = sb.toString();

        try {
            p = httpMethod.toUpperCase() + '&' + URLEncoder.encode(url + '&' + p, "UTF-8");
        }
        catch (UnsupportedEncodingException ignored) {
        }
        p = p + '&' + apiSecret;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("The sig source is [{}]", p);
        }
        return DigestUtils.md5Hex(p);
    }

    public static String generateSignature(Map<String, String> params, AuthorizationHeader authorizationHeader, String apiSecret,
            String httpMethod, String url) {
        Map<String, String> paramsToSign = new HashMap<String, String>();
        paramsToSign.putAll(params);
        // if (authorizationHeader.getSessionKey() != null) {
        // 如果sessionkey为null则设置一个空字符串参数 不然服务器端的签名认证无法通过
        paramsToSign.put("session_key", authorizationHeader.getSessionKey() == null ? "" : authorizationHeader.getSessionKey());
        // }
        paramsToSign.put("api_key", authorizationHeader.getApiKey());
        paramsToSign.put("kauth_signature_method", authorizationHeader.getSignatureMethod());
        paramsToSign.put("kauth_timestamp", authorizationHeader.getTimestamp());
        paramsToSign.put("kauth_nonce", authorizationHeader.getNonce());
        paramsToSign.put("kauth_version", authorizationHeader.getVersion());
        return generateSignature(paramsToSign, apiSecret, httpMethod, url);
    }
}
